package main

import (
	"context"
	feedserver "hertz_demo/kitex/feed/kitex_gen/feedserver"
	"hertz_demo/orm"
	"hertz_demo/orm/cache"
	"hertz_demo/orm/db"
	"time"
)

// FeedServiceImpl implements the last service interface defined in the IDL.
type FeedServiceImpl struct{}

// GetVideoFeed implements the FeedServiceImpl interface.
func (s *FeedServiceImpl) GetVideoFeed(ctx context.Context, req *feedserver.GetVideoFeedRequest) (resp *feedserver.GetVideoFeedResponse, err error) {
	// TODO: Your code here...
	resp = new(feedserver.GetVideoFeedResponse)
	// var result []models.Video
	videoIdList, err := cache.GetVideoFeed(req.LatestTime)
	if err != nil {
		return
	}
	var dbVideoList []db.Video
	if err = db.DB.Model(&db.Video{}).Find(&dbVideoList, videoIdList).Error; err != nil {
		return
	}
	var userIdList []int64
	for _, dbVideo := range dbVideoList {
		userIdList = append(userIdList, dbVideo.UserId)
	}
	var dbUserList []db.User
	if err = db.DB.Model(&db.User{}).Find(&dbUserList, userIdList).Error; err != nil {
		return
	}
	var followList []int64
	var favouriteList []int64
	if req.UserId != 0 {
		if err = db.DB.Model(&db.FollowRelation{}).Select("follow_user_id").Where("user_id=?", req.UserId).Find(&followList).Error; err != nil {
			return
		}
		if err = db.DB.Model(&db.FavouriteRelation{}).Select("video_id").Where("user_id=?", req.UserId).Find(&followList).Error; err != nil {
			return
		}
		followList = orm.GetIntersection(followList, userIdList)
		favouriteList = orm.GetIntersection(favouriteList, videoIdList)
	}
	nextTime := time.Now().Unix()
	for _, dbVideo := range dbVideoList {
		isFollow := false
		for _, id := range followList {
			if id == dbVideo.UserId {
				isFollow = true
				break
			}
		}
		isFavourite := false
		for _, id := range favouriteList {
			if id == dbVideo.ID {
				isFavourite = true
				break
			}
		}
		videoAuthor := feedserver.User{
			ID:       dbVideo.UserId,
			IsFollow: isFollow,
		}
		for _, dbUser := range dbUserList {
			if dbUser.ID == dbVideo.UserId {
				videoAuthor.Name = dbUser.Name
				videoAuthor.FollowCount = dbUser.FollowCount
				videoAuthor.FollowerCount = dbUser.FollowerCount
				break
			}
		}
		video := feedserver.Video{
			ID:             dbVideo.ID,
			Author:         &videoAuthor,
			Title:          dbVideo.Title,
			PlayUrl:        dbVideo.PlayUrl,
			CoverUrl:       dbVideo.CoverUrl,
			FavouriteCount: dbVideo.FavouriteCount,
			CommentCount:   dbVideo.CommentCount,
			IsFavourite:    isFavourite,
		}
		resp.Result_ = append(resp.Result_, &video)

		oldestTime := dbVideo.CreatedAt.Unix()
		if oldestTime < nextTime {
			nextTime = oldestTime
		}
	}
	resp.NextTime = nextTime
	return
}
